package org.example.controller;

import org.example.entity.User;
import org.example.service.UserService;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import reactor.core.scheduler.Scheduler;
import reactor.core.scheduler.Schedulers;

import javax.validation.constraints.NotNull;
import javax.validation.constraints.Positive;

/**
 * TODO 类功能介绍及重点或容易混淆点的说明。
 *
 * @version 1.0 2023/5/20 10:26 龙小南 新建类[说明]
 * @author: 龙小南
 * @Date: 2023/5/20 10:26
 * @Version 1.0[当前版本号]
 */
@Validated
@RestController
@RequestMapping("/users")
public class UserController {

    private final UserService userService;

    public UserController(UserService userService) {
        this.userService = userService;
    }

    /** ##### 参数校验 ####  start  ########## */
    @PostMapping("/")
    public Mono<User> createUser(@RequestBody @Validated User user){
        // 方式1: 吞吐量10
//        return userService.createUser(user);
        // 方式2: 吞吐量10
//        return Mono.fromFuture(userService.createUser2(user));
        // 方式3:
        return Mono.just("Hello WebFlux!")
                .publishOn(Schedulers.boundedElastic())
                .map(s -> userService.create(user));
    }

    /** 类上必须添加 @Validated 才能支持校验 */
    @GetMapping("/getUserById1/{userId}")
    public Mono<User> getUserById1(@PathVariable @NotNull @Positive(message = "主键必须大于0") Long userId){
        return userService.getUserById1(userId);
    }

    @GetMapping("/getUserById2")
    public Mono<User> getUserById2(@NotNull @Positive(message = "主键必须大于0") Long userId){
        return userService.getUserById1(userId);
    }
    /** ##### 参数校验 ####  end  ########## */


    @GetMapping("/{userId}")
    public Mono<User> getUserById(@PathVariable Long userId){
        return userService.getUserById1(userId);
    }

    @PutMapping("/{userId}")
    public Mono<User> updateUser(@PathVariable Long userId, @RequestBody User user){
        user.setId(userId);
        return userService.updateUser(user);
    }

    @DeleteMapping("/{userId}")
    public Mono<Void> deleteUser(@PathVariable Long userId){
        return  userService.deleteUser(userId);
    }

    @GetMapping("/hello")
    public Mono<String> helloWorld(){
        return Mono.just("Hello World!");
    }

    @GetMapping("/users")
    public Flux<User> listUsers(){
        return userService.listUsers();
    }
}
